package com.mezz.bones.framework.lock.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 用于标记需要加锁的方法。
 * <p>
 * 使用此注解可以对方法进行加锁处理。锁的键可以通过SpEL表达式动态计算。
 * </p>
 *
 * <p>
 * 注意事项：
 * 1. 锁的主键（lockKey）和业务键（businessKey）都可以通过SpEL动态计算，这提供了灵活的锁定机制。
 * 2. 如果一个线程在调用链中使用了多个锁，系统会以第一个锁生效。这意味着：
 *    - 在一个线程中，如果多个方法使用了不同的锁，当第一个锁被成功获取后，后续的锁请求将不会被重复加锁，避免了重复锁定的情况。
 *    - 后续的锁操作将被忽略，直到第一个锁释放。
 * 3. 确保锁的主键和业务键具有唯一性，以防止锁冲突或错误。
 * </p>
 *
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Lock {
    /**
     * 锁的主键，可以通过SpEL动态计算。
     *
     * @return 锁的主键
     */
    String lockKey();

    /**
     * 业务Key，可以通过SpEL动态计算。此键用于更细粒度的锁定。
     *
     * @return 业务Key
     */
    String businessKey() default "";

    /**
     * 锁的过期时间，单位毫秒，默认60000毫秒 (即60秒)
     */
    long expire() default 60000;

    /**
     * 获取锁的最大等待时间，单位毫秒，默认1000毫秒
     */
    long acquireTimeout() default 1000;
}
